package com.hk.core.authentication.api.reactive.menu;

import com.hk.commons.util.JsonUtils;
import com.hk.core.authentication.api.menus.Menu;
import com.hk.core.authentication.api.menus.MenuManager;
import com.hk.core.authentication.api.reactive.ReactiveSecurityContextUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;


/**
 * @author Kevin
 */
@Slf4j
@RequiredArgsConstructor
public abstract class AbstractReactiveMenuManager implements ReactiveMenuManager {

    protected abstract Flux<Menu> getAllMenu();

    @Override
    public Flux<Menu> getCurrentUserMenu() {
        return ReactiveSecurityContextUtils.getPrincipal().flatMapMany(principal -> {
            if (principal.isAdministrator()) {
                log.trace("The current login user [{}] is a system administrator", principal.getAccount());
                return getAllMenu();
            }
            var roles = principal.getRoles();
            var userPermissions = principal.getPermissions();
            log.trace("Reactive account:{},roles:{},permissions:{}", principal.getAccount(),
                    JsonUtils.serialize(roles), JsonUtils.serialize(userPermissions));
            return getAllMenu()
                    .collectList()
                    .flatMapMany(menus -> Flux.fromIterable(MenuManager.filterRolesAndPerms(menus, roles, userPermissions)));
        });
    }
}
